import * as $document from '@/api/document'
import * as _helper from '@/utils/helper'
import dayjs from 'dayjs'

import {UI_SET_PAGE, UI_SET_TOAST_WARNING_MSG} from './ui'
import {TASK_SET_TASKS} from './task'

const UPDATE_BLOCKS = 'UPDATE_BLOCKS'
const UPDATE_NAME = 'UPDATE_NAME'
const UPDATE_CONTENT = 'UPDATE_CONTENT'
const REGEN_CMPT_NO = 'REGEN_CMPT_NO'
const RESET_STATE = 'RESET_STATE'
const DEL_AUDIO_BLOCK_ITEM = 'DEL_AUDIO_BLOCK_ITEM'
const ADD_AUDIO_BLOCK_ITEM = 'ADD_AUDIO_BLOCK_ITEM'
export const SET_DOCUMENT = 'SET_DOCUMENT'
export const DOCUMENT_SET_DOCUMENTS = 'DOCUMENT_SET_DOCUMENTS'
export const DOCUMENT_UPDATE_DOCUMENTS = 'DOCUMENT_UPDATE_DOCUMENTS'
export const DOCUMENT_SET_OPERATION = 'DOCUMENT_SET_OPERATION'
export const DOCUMENT_RESET_DOCUMENT_ID = 'DOCUMENT_RESET_DOCUMENT_ID'
export const DOCUMENT_REPLACE_DOCUMENTS = 'DOCUMENT_REPLACE_DOCUMENTS'
export const DOCUMENT_RESET_DOCUMENTS = 'DOCUMENT_RESET_DOCUMENTS'
export const DOCUMENT_UNSHIRFT_DOCUMENTS = 'DOCUMENT_UNSHIRFT_DOCUMENTS'
export const DOCUMENT_RESET_DOCUMENTS_UNREAD_COUNT = 'DOCUMENT_RESET_DOCUMENTS_UNREAD_COUNT'
export const DOCUMENT_SET_PAGE_DOCUMENT_ID = 'DOCUMENT_SET_PAGE_DOCUMENT_ID'
export const DOCUMENT_SET_UPLOADING_MEDIA_NUM = 'DOCUMENT_SET_UPLOADING_MEDIA_NUM'
export const DOCUMENT_SET_PAGE_DOCUMENTS_LOADED = 'DOCUMENT_SET_PAGE_DOCUMENTS_LOADED'
export const DOCUMENT_SET_NAV_TYPE = 'DOCUMENT_SET_NAV_TYPE'
export const DOCUMENT_SET_UNREAD_COUNT = 'DOCUMENT_SET_UNREAD_COUNT'

const state = () => {
  return {
    id: 0,
    name: '',
    contentBlock: {
      id: _helper.genCmptNo(0),
      type: 'text',
      value: ''
    },
    audioBlocks: [],
    pageDocumentId: 0,
    pageDocumentsLoaded: false,
    document: {
      id: 0,
      name: '',
      user: {
        id: 0,
        nickName: '',
        avatarUrl: ''
      },
      data: {
        blocks: []
      }
    },
    documents: [],
    uploadingMediaNum: 0,
    operation: '',
    navType: 'published',
    unreadCount: 0,
  }
}

// getters
const getters = {
  name: state => state.name,
  navType: state => state.navType,
  operation: state => state.operation,
  uploadingMediaNum: state => state.uploadingMediaNum,
  pageDocumentId: state => state.pageDocumentId,
  pageDocumentsLoaded: state => state.pageDocumentsLoaded,
  unreadCount: state => state.unreadCount,
  document (state) {
    return state.document
  },
  documents (state) {
    let t = []
    state.documents.forEach(n => {
      let createdAtName = _helper.timeName(n.createdAt, 'YY-MM-DD HH:mm')
      n.createdAtName = createdAtName
      let updatedAtName = _helper.timeName(n.updatedAt, 'YY-MM-DD HH:mm')
      n.updatedAtName = updatedAtName
      t.push(n)
    })
    return t
  },
  isCreateAble (state, gettters, rootState, rootGetters) {
    let contentBlock = gettters.contentBlock
    let blocks = rootState.blocks.blocks
    if ((!contentBlock.value && blocks.length === 0) || gettters.uploadingMediaNum > 0) return false
    return true
  },
  audioBlocks: state => state.audioBlocks,
  contentBlock: state => state.contentBlock,
}

// actions
const actions = {
  async onCreate ({ dispatch, commit, state: {document, name, contentBlock, audioBlocks, operation}, rootState }, opts = {endAt: null}) {
    let endAt = opts.endAt
    if (operation === 'copy') {
      document.id = 0
    }
    if (!name) {
      commit(UI_SET_TOAST_WARNING_MSG, '作业标题不能为空！', {root: true})
      return
    }
    let blocks = getBlocks({contentBlock, blocks: rootState.blocks.blocks})
    if (blocks.length === 0) {
      commit(UI_SET_TOAST_WARNING_MSG, '作业内容不能为空！', {root: true})
      return
    }
    let res = await $document.create({id: document.id, name, data: {blocks}, endAt})
    dispatch('resetBlocks', false, {root: true})
    dispatch('setTriggerClearUploadQueue', null, {root: true})
    commit(SET_DOCUMENT, {...res, t: new Date()})
    commit(DOCUMENT_UPDATE_DOCUMENTS, {id: res.id, document: res})
    return res
  },
  async publish ({ dispatch, commit, state: {name, contentBlock, audioBlocks}, rootState }, {groupIds, endAt, prePublishAt}) {
    if (groupIds.length === 0) {
      commit(UI_SET_TOAST_WARNING_MSG, '请选择班级！', {root: true})
      return
    }

    let ct = dayjs()
    if (endAt) {
      let flag = ct.isBefore(dayjs(endAt))
      if (!flag) {
        commit(UI_SET_TOAST_WARNING_MSG, '截止时间必须大于当前时间！', {root: true})
        return
      }
    }

    if (prePublishAt) {
      let _endAt = dayjs(endAt)
      let _prePublishAt = dayjs(prePublishAt)
      let flag = _endAt.isBefore(_prePublishAt)
      if (flag) {
        commit(UI_SET_TOAST_WARNING_MSG, '预发布时间必须小于截止时间', {root: true})
        return
      }
      flag = ct.isBefore(_prePublishAt)
      if (!flag) {
        commit(UI_SET_TOAST_WARNING_MSG, '预发布时间必须大于当前时间', {root: true})
        return
      }
    }
    let doc = await dispatch('onCreate', {endAt})
    let tasks = await $document.publish({documentId: doc.id, groupIds, endAt, prePublishAt})
    return tasks
  },
  updateName ({ commit, state, rootState }, value) {
    commit(UPDATE_NAME, value)
  },
  setUploadingMediaNum ({ commit, state, rootState }, num) {
    commit(DOCUMENT_SET_UPLOADING_MEDIA_NUM, num)
  },
  setPageDocumentsLoaded ({ commit, state, rootState }, flag) {
    commit(DOCUMENT_SET_PAGE_DOCUMENTS_LOADED, flag)
  },
  setPageDocumentId ({ commit, state, rootState }, documentId) {
    commit(DOCUMENT_SET_PAGE_DOCUMENT_ID, documentId)
  },
  async getByPage ({ commit, state, rootState }, { pi }) {
    let cache = true
    if (pi === 0) {
      commit(DOCUMENT_RESET_DOCUMENTS)
      cache = false
    }
    let page = await $document.getByPage({pageIndex: pi, cache})
    commit(DOCUMENT_SET_DOCUMENTS, page.rows)
    let {totalCount, hasMore, totalPages, pageSize, pageIndex} = page
    commit(UI_SET_PAGE, {totalCount, hasMore, totalPages, pageIndex, pageSize}, {root: true})
  },
  updateContent ({ commit, state, rootState }, value) {
    commit(UPDATE_CONTENT, value)
  },
  delAudioBlockItem ({ commit, state, rootState }, idx) {
    commit(DEL_AUDIO_BLOCK_ITEM, idx)
  },
  addAudioBlockItem ({ commit, state, rootState }, material) {
    commit(ADD_AUDIO_BLOCK_ITEM, material)
  },
  resetDocuments ({ commit, state, rootState }) {
    commit(DOCUMENT_RESET_DOCUMENTS)
  },
  async fetchDocument ({ dispatch, commit, state, rootState }, documentId) {
    let res = await $document.getById(documentId)
    commit(SET_DOCUMENT, res)
    return res
  },
  async getUnpublishes ({ dispatch, commit, state, rootState }) {
    let documents = await $document.getUnpublishes()
    commit('document/DOCUMENT_REPLACE_DOCUMENTS', documents, {root: true})
    return documents
  },
}

// mutations
const mutations = {
  UPDATE_NAME (state, value) {
    state.name = value
  },
  DOCUMENT_SET_NAV_TYPE (state, value) {
    state.navType = value
  },
  DOCUMENT_SET_UPLOADING_MEDIA_NUM (state, num) {
    state.uploadingMediaNum = num
  },
  DOCUMENT_SET_PAGE_DOCUMENTS_LOADED (state, flag) {
    state.pageDocumentsLoaded = flag
  },
  DOCUMENT_SET_PAGE_DOCUMENT_ID (state, documentId) {
    state.pageDocumentId = documentId
  },
  UPDATE_CONTENT (state, value) {
    state.contentBlock.value = value
  },
  DOCUMENT_RESET_DOCUMENT_ID (state) {
    state.document.id = 0
  },
  REGEN_CMPT_NO (state) {
    state.contentBlock.id = _helper.genCmptNo(0)
  },
  DEL_AUDIO_BLOCK_ITEM (state, idx) {
    let t = []
    state.audioBlocks.forEach((n, i) => {
      if (i === idx) return
      t.push(n)
    })
    state.audioBlocks = t
  },
  ADD_AUDIO_BLOCK_ITEM (state, material) {
    state.audioBlocks.push(material)
  },
  SET_DOCUMENT (state, document) {
    state.document = document
  },
  DOCUMENT_SET_OPERATION (state, operation) {
    state.operation = operation
  },
  DOCUMENT_SET_DOCUMENTS (state, documents) {
    state.documents = [...state.documents, ...documents]
  },
  DOCUMENT_UPDATE_DOCUMENTS (state, {id, document}) {
    let idx = -1
    for (var i = 0; i < state.documents.length; i++) {
      let t = state.documents[i]
      if (t.id === id) {
        idx = i
        break
      }
    }
    if (idx === -1) return
    state.documents[idx] = document
  },
  DOCUMENT_REPLACE_DOCUMENTS (state, documents) {
    state.documents = documents
  },
  DOCUMENT_RESET_DOCUMENTS (state) {
    state.documents = []
  },
  DOCUMENT_SET_UNREAD_COUNT (state, count) {
    state.unreadCount = count
  },
  DOCUMENT_UNSHIRFT_DOCUMENTS (state, document) {
    let idx = state.documents.findIndex(n => n.id === document.id)
    if (idx >= 0) {
      let t = []
      state.documents.forEach((n, i) => {
        if (i === idx) n = document
        t.push(n)
      })
      state.documents = t
    } else {
      state.documents.unshift(document)
    }
  },
  RESET_STATE (state) {
    state.name = ''
    state.contentBlock = {
      id: _helper.genCmptNo(0),
      value: ''
    }
    state.audioBlocks = []
  },
  DOCUMENT_RESET_DOCUMENTS_UNREAD_COUNT (state, {documentId, unreadCount}) {
    let idx = state.documents.findIndex((n, i) => n.id === documentId)
    if (idx < 0) return
    state.documents[idx].unreadCount = unreadCount
  },
}

export default {
  namespaced: true,
  state,
  getters,
  actions,
  mutations
}

const getBlocks = ({contentBlock, blocks}) => {
  let t = []
  if (contentBlock.value) {
    contentBlock.type = 'text'
    t.push(contentBlock)
  }
  t = t.concat(blocks)
  return t
}
